package com.example.filedemo.manyformat.extracttext.anotherdemo;

import com.example.filedemo.constant.Constants;
import org.apache.pdfbox.io.RandomAccess;
import org.apache.pdfbox.io.RandomAccessFile;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.poi.hslf.HSLFSlideShow;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.model.TextRun;
import org.apache.poi.hslf.usermodel.SlideShow;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xslf.extractor.XSLFPowerPointExtractor;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.extractor.XWPFWordExtractor;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.dom4j.Document;
import org.dom4j.io.SAXReader;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 获取后缀为doc、docx、xls、xlsx、ppt、pptx、pdf、xml的文件中的纯文本
 *
 * <p>
 * .
 *
 * @author little_lunatic
 * @date 2023-02-02
 */
public class ExtractPlainText {
        public static void main(String[] args) {
            // 测试获取doc中的文本
            System.out.println(extractDoc(Constants.doc));

            // 测试获取docx中的文本
            System.out.println(extractDocx(Constants.docx));

            // 测试获取xls中的文本
            System.out.println(extractXls(Constants.xls));

            // 测试获取xlsx中的文本
            System.out.println(extractXlsx(Constants.xlsx));

            // 测试获取ppt中的文本
            System.out.println(extractPpt(Constants.ppt));

            // 测试获取pptx中的文本
            System.out.println(extractPptx(Constants.pptx));

            // 测试获取pdf中的文本
            System.out.println(extractPdf(Constants.pdf));

            // 测试获取xml中的文本
            System.out.println(extractXml(Constants.xml));
        }

        /**
         * 获取doc中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractDoc(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                WordExtractor extractor = new WordExtractor(in);
                return extractor.getText();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 获取docx中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractDocx(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                XWPFDocument xdoc = new XWPFDocument(in);
                XWPFWordExtractor extractor = new XWPFWordExtractor(xdoc);
                return extractor.getText();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 获取xls中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractXls(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                Workbook workbook = new HSSFWorkbook(in);
                return workbook2String(workbook);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 获取xlsx中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractXlsx(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                Workbook workbook = new XSSFWorkbook(in);
                return workbook2String(workbook);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        private static String workbook2String(Workbook workbook) {
            StringBuffer sb = new StringBuffer();
            if (workbook != null) {
                for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
                    // 获得当前sheet工作表
                    Sheet sheet = workbook.getSheetAt(sheetNum);
                    if (sheet == null) {
                        continue;
                    }
                    // 获得当前sheet的开始行
                    int firstRowNum = sheet.getFirstRowNum();
                    // 获得当前sheet的结束行
                    int lastRowNum = sheet.getLastRowNum();
                    // 循环除了第一行的所有行
                    sb.append(sheet.getSheetName() + "\n");
                    for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
                        // 获得当前行
                        Row row = sheet.getRow(rowNum);
                        if (row == null || row.getPhysicalNumberOfCells() == 0) {
                            /* String[] a=new String[0]; list.add(a); */
                            // sb.append("\r\n");
                            continue;
                        } // 获得当前行的开始列
                        int firstCellNum = row.getFirstCellNum();
                        // 获得当前行的列数
                        int lastCellNum = row.getLastCellNum();
                        // String[] cells = new
                        // String[row.getPhysicalNumberOfCells()];
                        // 循环当前行
                        for (int cellNum = firstCellNum; cellNum < lastCellNum; cellNum++) {
                            Cell cell = row.getCell(cellNum);
                            String value = cellValue(cell);
                            if (!"".equals(value)) {
                                sb.append(value);
                                sb.append(",");
                            }
                        }
                    }
                    sb.append("\n");
                }
            }
            return sb.toString();
        }

        /**
         * 获得Excel格子里的内容
         *
         * @param cell 每个格子
         * @return
         */
        private static String cellValue(Cell cell) {
            String cellValue = "";
            if (cell == null) {
                return cellValue;
            }
            // 把数字当成String来读，避免出现1读成1.0的情况
            // if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            // // cell.setCellType(Cell.CELL_TYPE_STRING);
            //
            // }
            // 判断数据的类型
            switch (cell.getCellType()) {
                case Cell.CELL_TYPE_NUMERIC: // 数字
                    // cellValue = String.valueOf(cell.getNumericCellValue());
                    short format = cell.getCellStyle().getDataFormat();
                    SimpleDateFormat sdf = null;
                    if (format == 14 || format == 31 || format == 57 || format == 58
                            || (176 <= format && format <= 178)
                            || (182 <= format && format <= 196)
                            || (210 <= format && format <= 213) || (208 == format)) {
                        if (format == 14) {
                            sdf = new SimpleDateFormat("yyyy/MM/dd");
                        } else {
                            sdf = new SimpleDateFormat("yyyy年MM月dd日");
                        }

                        double value = cell.getNumericCellValue();
                        Date date = org.apache.poi.ss.usermodel.DateUtil
                                .getJavaDate(value);
                        if (date == null || "".equals(date)) {
                            cellValue = "";
                        }
                        try {
                            cellValue = (sdf.format(date));
                        } catch (Exception e) {
                            e.printStackTrace();
                            cellValue = "";
                        }
                    } else { // 不是日期格式
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        String temp = cell.getStringCellValue();
                        // 判断是否包含小数点，如果不含小数点，则以字符串读取，如果含小数点，则转换为Double类型的字符串
                        if (temp.indexOf(".") > -1) {
                            cellValue = (String.valueOf(new Double(temp)).trim());
                        } else {
                            cellValue = (temp.trim());
                        }
                    }
                    break;
                case Cell.CELL_TYPE_STRING: // 字符串
                    cellValue = String.valueOf(cell.getStringCellValue());
                    break;
                case Cell.CELL_TYPE_BOOLEAN: // Boolean
                    cellValue = String.valueOf(cell.getBooleanCellValue());
                    break;
                case Cell.CELL_TYPE_FORMULA: // 公式
                    cellValue = String.valueOf(cell.getCellFormula());
                    break;
                case Cell.CELL_TYPE_BLANK: // 空值
                    cellValue = "";
                    break;
                case Cell.CELL_TYPE_ERROR: // 故障
                    cellValue = "";// 非法字符
                    break;
                default:
                    cellValue = "";// 未知类型
                    break;
            }
            return cellValue;
        }

        /**
         * 获取ppt中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractPpt(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                StringBuffer content = new StringBuffer();
                SlideShow ss = new SlideShow(new HSLFSlideShow(in));
                Slide[] slides = ss.getSlides();// 获得每一张幻灯片
                for (int i = 0; i < slides.length; i++) {
                    TextRun[] t = slides[i].getTextRuns();// 为了取得幻灯片的文字内容，建立TextRun
                    for (int j = 0; j < t.length; j++) {
                        content.append(t[j].getText());// 这里会将文字内容加到content中去
                    }
                    content.append(slides[i].getTitle());
                }
                return content.toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 获取pptx中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractPptx(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                XMLSlideShow slide = new XMLSlideShow(in);
                XSLFPowerPointExtractor extractor = new XSLFPowerPointExtractor(
                        slide);
                return extractor.getText();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        /**
         * 获取pdf中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractPdf(String filePath) {
            RandomAccess rf = null;
            PDDocument document = null;
            try {
                rf = new RandomAccessFile(new File(filePath), "r");
                PDFParser parser = new PDFParser(rf);
                parser.parse();
                document = parser.getPDDocument();
                PDFTextStripper stripper = new PDFTextStripper();
                String text = stripper.getText(document);
                document.close();
                return text;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (document != null) {
                    try {
                        document.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (rf != null) {
                    try {
                        rf.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return null;
        }

        /**
         * 获取xml中的文本
         *
         * @param filePath 文件全路径
         * @return 文本
         * @author 明快de玄米61
         * @date 2022/12/18 23:22
         **/
        private static String extractXml(String filePath) {
            try (
                    InputStream in = new FileInputStream(filePath)
            ) {
                Document doc = new SAXReader().read(in);
                return doc.asXML();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
}